﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Noris.Schedule.Support.Services;
using System.Drawing;
using System.Windows.Forms;
using Noris.Schedule.Planning.ProcessData;
using Noris.Schedule.Support.Core;
using Noris.Schedule.Support;

namespace Noris.Schedule.Planning.Services
{
	#region ROZDĚLENÍ PŘÍJMU NA OSU S
	/// <summary>
	/// Funkce pro rozdělení příjmu na osu S na více dílčích příjmů, a přeplánování
	/// </summary>
	internal class AxisSSplit : IFunctionMenuItem
	{
		/// <summary>
		/// Tady funkce deklaruje, pro které případy chce být vidět v nabídce.
		/// A pokud ano, tak jak se jmenuje, kde v nabídce je a jaký má obrázek.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsFunctionSuitableFor(FunctionMenuItemSuitableArgs args)
		{
            // Funkce je dostupná jen v debug modu:
            if (!Steward.DebugMode)
                return false;

			// Element lze rozdělit buď na grafu typu TaskCapacityLink, pokud je kliknuto na element, a jde o element třídy WorkUnit:
			bool isSuitable1 = (
				args.KeyGraphMode == RowGraphMode.TaskCapacityLink &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberWork);
			//  ... anebo v grafu typu Gant, pokud je element ze třídy Task:
			bool isSuitable2 = (
				args.KeyGraphMode == RowGraphMode.Gantt &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberTask);
			bool isSuitable = isSuitable1 || isSuitable2;
			if (isSuitable)
			{
				args.MenuCaption = "Rozdělit příjem na osu S";
				args.MenuToolTipText = "Umožní rozdělit příjem na osu S na více dílčích návrhů na příjem.";
				args.MenuImage = PicLibrary22.Transformshearleft_FromFile;
				args.MenuGroup = "TASK";
				args.EnabledStateDependingOnElement = true;
				args.MenuOrder = -250;
			}
			return isSuitable;
		}
		/// <summary>
		/// Dotaz na Enabled této položky menu, při znalosti konkrétních podmínek (máme vybraný konkrétní element).
		/// Výstup = true nyní je tato položka menu dostupná
		/// false = nyní je nedostupná
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsMenuItemEnabledFor(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return false;

			CapacityPlanWorkItemCls task = planningData.FindTaskC(args.ClickedItem);
			if (task == null) return false;

			// Funkci lze spustit jen pro návrhy na příjem:
			switch (task.AxisData.ChangeType)
			{
				case PlanSAxisChangeType.IncrementByPlanProductOrder:
				case PlanSAxisChangeType.IncrementByPlanByProductSuitable:
				case PlanSAxisChangeType.IncrementByPlanByProductDissonant:
					return true;
			}
			return false;
		}
		/// <summary>
		/// Vstupní metoda do výkonné části pluginu
		/// </summary>
		/// <param name="args"></param>
		void IFunctionMenuItem.Run(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return;

			CapacityPlanWorkItemCls task = planningData.FindTaskC(args.ClickedItem);
			if (task == null) return;

			// Rozdělím příjem na dvě poloviny:
			decimal qtyRequired = task.QtyRequired;
            int roundBase = (qtyRequired % 1 == 0 ? 0 : 1);
            decimal qtySplit1 = Math.Round(qtyRequired / 3M, roundBase);
            decimal qtySplit2 = qtyRequired - qtySplit1;
            if (qtySplit1 <= 0M || qtySplit2 <= 0M)
                if (qtySplit1 <= 0M || qtySplit2 <= 0M)
			{
				Dialog.ShowWarning(MessageInfo.Get("Po rozdělení by toho moc nezbylo, dělit se nebude."));
				return;
			}

			// Sestavím data pro rozdělení a požádám o provedení:
			PlanningInteractiveSplitAxisSArgs splitArgs = new PlanningInteractiveSplitAxisSArgs();
			splitArgs.SplitItemSource = args.ClickedItem;
			splitArgs.SplitItemList.Add(new PlanningInteractiveSplitAxisSItemArgs(qtySplit1, Noris.Schedule.Support.TimeRange.TimeDirection.ToFuture, SplitAxisSQtyAdjustmentMode.None));
            splitArgs.SplitItemList.Add(new PlanningInteractiveSplitAxisSItemArgs(qtySplit2, Noris.Schedule.Support.TimeRange.TimeDirection.ToFuture, SplitAxisSQtyAdjustmentMode.AdjustByElementLoss));

			planningData.InteractiveSplitAxisS(splitArgs);

			// Výstup = souhrn změněných řádků:
			splitArgs.ResultCopyTo(args);
		}
	}
	#endregion
	#region ROZDĚLENÍ JEDNOHO KAPACITNÍHO PRŮCHODU NA VÍCE PRŮCHODŮ, V RÁMCI JEDNOHO TASKU
	/// <summary>
	/// Funkce pro rozdělení kapacitního průchodu na více dílčích průchodů, a přeplánování
	/// </summary>
	internal class TaskCSplit : IFunctionMenuItem
	{
		/// <summary>
		/// Tady funkce deklaruje, pro které případy chce být vidět v nabídce.
		/// A pokud ano, tak jak se jmenuje, kde v nabídce je a jaký má obrázek.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsFunctionSuitableFor(FunctionMenuItemSuitableArgs args)
		{
			// Funkce je dostupná jen v debug modu:
			if (!Steward.DebugMode)
                return false;

			// Element lze rozdělit jen na grafu typu TaskCapacityLink, pokud je kliknuto na element, a pokud jde o element třídy WorkUnit:
			bool isSuitable = (
				args.KeyGraphMode == RowGraphMode.TaskCapacityLink &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberWork);
			if (isSuitable)
			{
				args.MenuCaption = "Rozdělit na dva paralelní průchody";
				args.MenuToolTipText = "Umožní rozdělit zpracování na dva průchody, v rámci jedné operace.";
				args.MenuImage = PicLibrary22.Transformshearleft_FromFile;
				args.MenuGroup = "TASK";
				args.MenuOrder = -240;
				args.EnabledStateDependingOnElement = true;
			}
			return isSuitable;
		}
		/// <summary>
		/// Dotaz na Enabled této položky menu, při znalosti konkrétních podmínek (máme vybraný konkrétní element).
		/// Výstup = true nyní je tato položka menu dostupná
		/// false = nyní je nedostupná
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsMenuItemEnabledFor(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return false;

			CapacityPlanWorkItemCls task = planningData.FindTaskC(args.ClickedItem);
			if (task == null) return false;

			// Funkci lze spustit jen pro návrhy na příjem a pro výrobní příkazy:
			switch (task.AxisData.ChangeType)
			{
				case PlanSAxisChangeType.IncrementByPlanProductOrder:
				case PlanSAxisChangeType.IncrementByPlanByProductSuitable:
				case PlanSAxisChangeType.IncrementByPlanByProductDissonant:
					return true;
				case PlanSAxisChangeType.IncrementByRealProductOrder:
				case PlanSAxisChangeType.IncrementByRealByProductSuitable:
				case PlanSAxisChangeType.IncrementByRealByProductDissonant:
					return true;
			}
			return false;
		}
		/// <summary>
		/// Vstupní metoda do výkonné části pluginu
		/// </summary>
		/// <param name="args"></param>
		void IFunctionMenuItem.Run(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return;

			WorkPassCls pass = planningData.FindWorkPass(args.ClickedItem);

			// Rozdělím průchod na dvě poloviny:
			decimal qtyRequired = pass.QtyRequired;
            int roundBase = (qtyRequired % 1 == 0 ? 0 : 2);
            decimal qtySplit1 = Math.Round(qtyRequired / 2M, roundBase);
			decimal qtySplit2 = qtyRequired - qtySplit1;
			if (qtySplit1 <= 0M || qtySplit2 <= 0M)
			{
				Dialog.ShowWarning(MessageInfo.Get("Po rozdělení by toho moc nezbylo, dělit se nebude."));
				return;
			}
            bool isVolatile = ((qtySplit1 + qtySplit2) != qtyRequired);

			// Sestavím data pro rozdělení a požádám o provedení:
			PlanningInteractiveSplitTaskCArgs splitArgs = new PlanningInteractiveSplitTaskCArgs();
			splitArgs.SplitItemSource = args.ClickedItem;
            splitArgs.SplitItemList.Add(new PlanningInteractiveSplitTaskCItemArgs(qtySplit1, new TimeVector(DateTime.MinValue, TimeRange.TimeDirection.ToFuture)));
			splitArgs.SplitItemList.Add(new PlanningInteractiveSplitTaskCItemArgs(qtySplit2, isVolatile, new TimeVector(DateTime.MinValue, TimeRange.TimeDirection.ToFuture)));

			planningData.InteractiveSplitTaskC(splitArgs);

			// Výstup = souhrn změněných řádků:
			splitArgs.ResultCopyTo(args);
		}
	}
	#endregion
}
